////////////////////////////////////////////////////////////////////////////////////////
//File		:	DXControl.h
//Author	:	Nick Bullock - nbullock@fullsail.com
//				Full Sail University
//				DirectX - 03/03/2009
//Purpose	:	Wrapper to control DirectX9 device interface.
////////////////////////////////////////////////////////////////////////////////////////
#ifndef DXCONTROL_H_
#define DXCONTROL_H_

#include "Includes.h"
// Classes and structs defined in this file.
class DXDeviceControl;
struct DXDeviceSettings;

////////////////////////////////////////////////////////////////////////////////////////
//Structs
////////////////////////////////////////////////////////////////////////////////////////
struct DXDeviceSettings
{
	UINT AdapterOrdinal;
	D3DDEVTYPE DeviceType;
	D3DFORMAT AdapterFormat;
	DWORD BehaviorFlags;
	D3DPRESENT_PARAMETERS PresentParams;
};

struct DXDeviceState
{
	BOOL IsDeviceInitialized;	// TRUE, if the IDirect3DDevice9 is initialized
	BOOL IsSpriteInitialized;	// TRUE, if the ID3DXSprite is initialized
	BOOL IsFontInitialized;		// TRUE, if the ID3DXFont is initialized
	BOOL IsLineInitialized;		// TRUE, if the ID3DXLine is initialized
	BOOL IsWindowed;			// TRUE, if the device is windowed
	BOOL LostDevice;			// TRUE, if the device is not operational
};

////////////////////////////////////////////////////////////////////////////////////////
//Classes
////////////////////////////////////////////////////////////////////////////////////////
class DXDeviceControl
{
private:
	/*if using static memory to initialize the class, these may not be needed*/
	static DXDeviceControl*		m_pInstance;	// pointer to the singleton class
	static unsigned int			m_references;	// how many objects point to this class

	LPDIRECT3D9					m_pd3d;			// pointer to the Direct3D9 interface
	LPDIRECT3DDEVICE9			m_pdev;			// pointer to the device interface
	LPD3DXFONT					m_pFont;		// pointer to the font interface
	LPD3DXLINE					m_pLine;		// pointer to the line interface
	LPD3DXSPRITE				m_pSprite;		// pointer to the sprite interface
	DXDeviceSettings			m_currentDeviceSettings; // current device settings
	DXDeviceState				m_deviceState;	// current device state
	unsigned int				m_screenWidth;	// desired screen width
	unsigned int				m_screenHeight;	// desired screen height
	/* if the device cannot handle the resolutiion, 
	the current desktop format will be used*/

	////////////////////////////////////////////////////////////////////////////////////
	//Functions	:	Disabled: Constructor, Copy Constructor, and Assignment Operator.
	////////////////////////////////////////////////////////////////////////////////////
	DXDeviceControl(void);
	DXDeviceControl(const DXDeviceControl &ref);
	DXDeviceControl* operator=(const DXDeviceControl &ref);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	Create
	//Purpose	:	Initialize all the member variables to their default values.
	//In		:	Nothing.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void Create(void);

public:
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	Destructor.
	////////////////////////////////////////////////////////////////////////////////////
	~DXDeviceControl(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Functions	:	Accessors.
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetInstance
	//Purpose	:	To create either a static or dynamic instance of the class.
	//In		:	Nothing.
	//Out		:	DXDeviceControl* - pointer to the instance of the class.
	////////////////////////////////////////////////////////////////////////////////////
	static DXDeviceControl* GetInstance(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetDevice
	//Purpose	:	Allow access to the device interface, there's more to DirectX than
	//				what this wrapper will do.
	//In		:	Nothing.
	//Out		:	LPDIRECT3DDEVICE9 - pointer to the Direct3D device interface.
	////////////////////////////////////////////////////////////////////////////////////
	LPDIRECT3DDEVICE9 GetDevice(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetFont
	//Purpose	:	Allow access to the DirectX Font pointer.
	//In		:	Nothing.
	//Out		:	LPD3DXFONT - pointer to the DirectX Font interface.
	////////////////////////////////////////////////////////////////////////////////////
	LPD3DXFONT GetFont(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetLine
	//Purpose	:	Allow access to the DirectX Line pointer.
	//In		:	Nothing.
	//Out		:	LPD3DXLINE - pointer to the DirectX Line interface.
	////////////////////////////////////////////////////////////////////////////////////
	LPD3DXLINE GetLine(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetSprite
	//Purpose	:	Allow access to the DirectX Sprite pointer.
	//In		:	Nothing.
	//Out		:	LPD3DXSPRITE - pointer to the DirectX Sprite interface.
	////////////////////////////////////////////////////////////////////////////////////
	LPD3DXSPRITE GetSprite(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetViewMatrix
	//Purpose	:	Get the current transform view matrix.
	//In		:	D3DMATRIX& - reference of a D3DMATRIX to be filled out.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void GetViewMatrix(D3DMATRIX& viewMat);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	GetProjectionMatrix
	//Purpose	:	Get the current transform projection matrix.
	//In		:	D3DMATRIX& - reference of a D3DMATRIX to be filled out.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void GetProjectionMatrix(D3DMATRIX& projMat);

	////////////////////////////////////////////////////////////////////////////////////
	//Functions	:	Accessors to get the current state of the interfaces.
	////////////////////////////////////////////////////////////////////////////////////
	BOOL IsDeviceInitialized(void);
	BOOL IsSpriteInitialized(void);
	BOOL IsFontInitialized(void);
	BOOL IsLineInitialized(void);
	BOOL IsDeviceWindowed(void);
	BOOL IsDeviceWorking(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Functions	:	Methods.
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	ReleaseInstance
	//Purpose	:	If using dynamic memory to manage the singleton class, this will
	//				release a reference count each time called, until none are left, 
	//				then this function will delete the dynamic memory that was created.
	//In		:	Nothing.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	static void ReleaseInstance(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	InitDevice
	//Purpose	:	Initializes the Direct3D device interface.
	//In		:	HWND - handle to the window.
	//				DXDeviceSettings* - pointer to a DXDeviceSettings struct.
	//				BOOL - TRUE, if the device will initialize in windowed mode.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool InitDevice(HWND hWnd, DXDeviceSettings* display = NULL, BOOL windowed = FALSE, BOOL bVsync = TRUE);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	InitSprite
	//Purpose	:	Initializes the DirectX Sprite interface associated with the device.
	//In		:	Nothing.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool InitSprite(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	InitFont
	//Purpose	:	Initializes the DirectX Font interface associated with the device.
	//In		:	char* - char array containing the typeface name.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool InitFont(char* const fontName = "Arial");
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	InitLine
	//Purpose	:	Initializes the DirectX Line interface associated with the device.
	//In		:	Nothing.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool InitLine(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	FindCurrentDisplaySettings
	//Purpose	:	Find the current display mode and color-bit depth of the desktop.
	//In		:	D3DPRESENT_PARAMETERS* - pointer to a D3DPRESENT_PARAMETERS struct.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool FindCurrentDisplaySettings(D3DPRESENT_PARAMETERS* const);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	CheckDevice
	//Purpose	:	Check the cooperation level of the device to determine if the device
	//				is ready to be reset.
	//In		:	Nothing.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool CheckDevice(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	ResetDevice
	//Purpose	:	Resets the device and Line, Font and Sprite, as well if initialized.
	//In		:	Nothing.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool ResetDevice(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	ToggleFullScreen
	//Purpose	:	Toggle the device display mode from windowed mode to fullscreen, and
	//				fullscreen mode to windowed.
	//In		:	Nothing.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool ToggleFullScreen(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	SetScreenSize
	//Purpose	:	Sets the current display resolution to the user defined parameters,
	//				if possible with the device.
	//In		:	unsigned int - the width of the screen resolution to change to.
	//				unsigned int - the height of the screen resolution to change to.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool SetScreenSize(unsigned width, unsigned height);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	SetScreenChange
	//Purpose	:	Commits the changes defined by ToggleFullScreen or SetScreenSize.
	//In		:	D3DPRESENT_PARAMETERS* - pointer to a D3DPRESENT_PARAMETERS struct.
	//Out		:	bool - true, if the function succeeds.
	////////////////////////////////////////////////////////////////////////////////////
	bool SetScreenChange(D3DPRESENT_PARAMETERS* const oldPresentParams);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	SetViewMatrix
	//Purpose	:	Sets the fixed function view matrix.
	//In		:	D3DMATRIX& - matrix reference to be used as the view matrix.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void SetViewMatrix(D3DMATRIX& viewMat);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	SetViewMatrix
	//Purpose	:	Sets the fixed function projection matrix.
	//In		:	D3DMATRIX& - matrix reference to be used as the projection matrix.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void SetProjectionMatrix(D3DMATRIX& projMat);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	KillControl
	//Purpose	:	Releases all the COM objects that are initialized.
	//In		:	Nothing.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void KillControl(void);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	BeginRendering
	//Purpose	:	Clears the buffers and begins the scene for rendering.
	//In		:	bool - true, to clear the stencil planes.
	//				bool - true, to clear the target surface.
	//				bool - true, to clear the target z buffer.
	//				unsigned char - (0-255) value for the clear color red component.
	//				unsigned char - (0-255) value for the clear color green component.
	//				unsigned char - (0-255) value for the clear color blue component.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void BeginRendering(bool stencil = false, bool target = false, bool zbuffer = false,
				unsigned char red = 0, unsigned char green = 0, unsigned char blue = 0);
	
	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	EndRendering
	//Purpose	:	Ends a scene that was begun and resents the contents of the next
	//				buffer in the sequence of back buffers owned by the device.
	//In		:	Nothing.
	//Out		:	Nothing.
	////////////////////////////////////////////////////////////////////////////////////
	void EndRendering(void);

	////////////////////////////////////////////////////////////////////////////////////
	//Function	:	DrawText
	//Purpose	:	Draws a string to the screen.
	//In		:	char* - the text string to draw to the screen.
	//				int - the x coordinate of the screen to draw the text.
	//				int - the y coordinate of the screen to draw the text.
	//				unsigned char - (0-255) value for the text color red component.
	//				unsigned char - (0-255) value for the text color green component.
	//				unsigned char - (0-255) value for the text color blue component.
	//				unsigned char - (0-255) value for the text color alpha component.
	//Out		:	bool - true, if the function succeeded.
	////////////////////////////////////////////////////////////////////////////////////
	bool DrawText(char* text, int xPos = 0, int yPos = 0,
				unsigned char red = 255, unsigned char green = 255, unsigned char blue = 255, unsigned char alpha = 255);
};
#endif /*DXCONTROL_H_*/